package cars;

import java.awt.Color;

import utils.Line;
import utils.Polygonal;
import utils.Position;

public class Car {

	private Position current_position;
	private Position previus_position;
	private Position next_position;
	private Color color;
	private Polygonal race;
	
	/**
	 * @param current_position
	 * @param previus_position
	 * @param next_position
	 * @param color
	 */
	public Car(Position current_position, Position previus_position,
			Position next_position, Color color) {
		super();
		this.current_position = current_position;
		this.previus_position = previus_position;
		this.next_position = next_position;
		
		this.race = new Polygonal();
		this.color = color;
	}

	public Polygonal getRace() {
		return race;
	}

	public void setRace(Polygonal race) {
		this.race = race;
	}

	/**
	 * @return the current_position
	 */
	public Position getCurrent_position() {
		return current_position;
	}

	/**
	 * @param current_position the current_position to set
	 */
	public void setCurrent_position(Position current_position) {
		this.current_position = current_position;
	}

	/**
	 * @return the previus_position
	 */
	public Position getPrevius_position() {
		return previus_position;
	}

	/**
	 * @param previus_position the previus_position to set
	 */
	public void setPrevius_position(Position previus_position) {
		this.previus_position = previus_position;
	}

	/**
	 * @return the next_position
	 */
	public Position getNext_position() {
		return next_position;
	}

	/**
	 * @param next_position the next_position to set
	 */
	public void setNext_position(Position next_position) {
		this.next_position = next_position;
	}

	/**
	 * @return the color
	 */
	public Color getColor() {
		return color;
	}

	/**
	 * @param color the color to set
	 */
	public void setColor(Color color) {
		this.color = color;
	}

	private Position calculateNextPositionUpLeft(Line line) {
		System.out.println("Siguiente UL");
		Position ps = new Position();
		int distance = (int)line.distance();
		System.out.println(distance);
		int direction = line.direction();
		switch(direction){
			//	Vertical
			case 1: 
					ps.setX(line.getB().getX()-distance);
					ps.setY(line.getB().getY());
					break;
			// Horizontal
			case 2: 
					ps.setX(line.getB().getX());
					ps.setY(line.getB().getY()-distance);
					break;
			// Diag Izq Arriba
			case 3:
					ps.setX(line.getB().getX()-(distance+1));
					ps.setY(line.getB().getY()-(distance+1));
					break;
			// Diag Derecha Arriba
			case 4:
					ps.setX(line.getB().getX());
					ps.setY(line.getB().getY()-(distance+1));
					break;
			// Diag Izq Abajo
			case 5:
					ps.setX(line.getB().getX()-(distance+1));
					ps.setY(line.getB().getY());
					break;
			// Diag Der Abajo
			case 6:
					ps.setX(line.getB().getX()+(distance-1));
					ps.setY(line.getB().getY()+(distance-1));
					break;

		}
		
		System.out.println(ps.toString());
		return ps;
	}

	public void moveUpLeft() {
		System.out.println("Izquierda Arriba");
				
		Position previus = new Position(this.getCurrent_position());
		Line line = new Line(this.getPrevius_position(),previus);
		this.setPrevius_position(previus);
		Position current = calculateNextPositionUpLeft(line);
		race.addPosition(current);
		this.setCurrent_position(current);		
	}

	private Position calculateNextPositionUp(Line line) {
		System.out.println("Siguiente U");
		Position ps = new Position();
		int distance = (int)line.distance();
		System.out.println(distance);
		int direction = line.direction();
		switch(direction){
			//	Vertical OK
			case 1: 
					ps.setX(line.getB().getX()+distance);
					ps.setY(line.getB().getY()+(distance-1));
					break;
			// Horizontal OK
			case 2: 
					ps.setX(line.getB().getX()+(distance+1));
					ps.setY(line.getB().getY()-1);
					break;
			// Diag Izq Arriba OK
			case 3:
					ps.setX(line.getB().getX()-(distance+1));
					ps.setY(line.getB().getY()-(distance+1));
					break;
			// Diag Derecha Arriba OK
			case 4:
					ps.setX(line.getB().getX()+(distance+1));
					ps.setY(line.getB().getY()+(distance+1));
					break;
			// Diag Izq Abajo OK
			case 5:
					ps.setX(line.getB().getX()-(distance-1));
					ps.setY(line.getB().getY()+(distance-1));
					break;
			// Diag Der Abajo OK
			case 6:
					ps.setX(line.getB().getX()+(distance+1));
					ps.setY(line.getB().getY()-(distance-1));
					break;

		}
		
		System.out.println(ps.toString());
		return ps;
	}
	
	

	public void moveUp() {
		System.out.println("Arriba");
		
		Position previus = new Position(this.getCurrent_position());
		Line line = new Line(this.getPrevius_position(),previus);
		this.setPrevius_position(previus);
		Position current = calculateNextPositionUp(line);
		this.setCurrent_position(current);
		
	}

	
	private Position calculateNextPositionUpRigth(Line line) {
		System.out.println("Siguiente UR");
		Position ps = new Position();
		int distance = (int)line.distance();
		System.out.println(distance);
		int direction = line.direction();
		switch(direction){
			//	Vertical OK
			case 1: 
					ps.setX(line.getB().getX()+distance);
					ps.setY(line.getB().getY()+(distance-1));
					break;
			// Horizontal OK
			case 2: 
					ps.setX(line.getB().getX()+(distance+1));
					ps.setY(line.getB().getY()-1);
					break;
			// Diag Izq Arriba OK
			case 3:
					ps.setX(line.getB().getX()-(distance+1));
					ps.setY(line.getB().getY()-(distance+1));
					break;
			// Diag Derecha Arriba OK
			case 4:
					ps.setX(line.getB().getX()+(distance+1));
					ps.setY(line.getB().getY()-(distance+1));
					break;
			// Diag Izq Abajo OK
			case 5:
					ps.setX(line.getB().getX()-(distance-1));
					ps.setY(line.getB().getY()+(distance-1));
					break;
			// Diag Der Abajo OK
			case 6:
					ps.setX(line.getB().getX()+(distance+1));
					ps.setY(line.getB().getY()-(distance-1));
					break;

		}
		
		System.out.println(ps.toString());
		return ps;
	}
	
	public void moveUpRight() {
		System.out.println("Derecha Arriba");
		
		Position previus = new Position(this.getCurrent_position());
		Line line = new Line(this.getPrevius_position(),previus);
		this.setPrevius_position(previus);
		Position current = calculateNextPositionUpRigth(line);
		this.setCurrent_position(current);
	}

	private Position calculateNextPositionLeft(Line line) {
		System.out.println("Siguiente L");
		Position ps = new Position();
		int distance = (int)line.distance();
		System.out.println(distance);
		int direction = line.direction();
		switch(direction){
			//	Vertical OK
			case 1: 
					ps.setX(line.getB().getX()-1);
					ps.setY(line.getB().getY()+distance);
					break;
			// Horizontal OK 
			case 2: 
					ps.setX(line.getB().getX()-(distance-1));
					ps.setY(line.getB().getY());
					break;
			// Diag Izq Arriba OK
			case 3:
					ps.setX(line.getB().getX()-(distance+1));
					ps.setY(line.getB().getY()-(distance));
					break;
			// Diag Derecha Arriba OK
			case 4:
					ps.setX(line.getB().getX()+(distance-1));
					ps.setY(line.getB().getY()-(distance));
					break;
			// Diag Izq Abajo OK
			case 5:
					ps.setX(line.getB().getX()-(distance+1));
					ps.setY(line.getB().getY()+(distance));
					break;
			// Diag Der Abajo OK
			case 6:
					ps.setX(line.getB().getX()+(distance-1));
					ps.setY(line.getB().getY()+(distance));
					break;

		}
		
		System.out.println(ps.toString());
		return ps;
	}
	
	
	public void moveLeft() {
		System.out.println("Izquierda");
		
		Position previus = new Position(this.getCurrent_position());
		Line line = new Line(this.getPrevius_position(),previus);
		this.setPrevius_position(previus);
		Position current = calculateNextPositionLeft(line);
		this.setCurrent_position(current);
	}

	
	private Position calculateNextPositionCenter(Line line) {
		System.out.println("Siguiente C");
		Position ps = new Position();
		int distance = (int)line.distance();
		System.out.println(distance);
		int direction = line.direction();
		switch(direction){
			//	Vertical OK
			case 1: 
					ps.setX(line.getB().getX());
					ps.setY(line.getB().getY()+(distance));
					break;
			// Horizontal OK
			case 2: 
					ps.setX(line.getB().getX()+(distance));
					ps.setY(line.getB().getY());
					break;
			// Diag Izq Arriba OK
			case 3:
					ps.setX(line.getB().getX()-(distance));
					ps.setY(line.getB().getY()-(distance));
					break;
			// Diag Derecha Arriba OK 
			case 4:
					ps.setX(line.getB().getX()+(distance));
					ps.setY(line.getB().getY()-(distance));
					break;
			// Diag Izq Abajo OK
			case 5:
					ps.setX(line.getB().getX()-(distance));
					ps.setY(line.getB().getY()+(distance));
					break;
			// Diag Der Abajo OK
			case 6:
					ps.setX(line.getB().getX()+(distance));
					ps.setY(line.getB().getY()+(distance));
					break;

		}
		
		System.out.println(ps.toString());
		return ps;
	}
	
	
	public void moveCenter() {
		System.out.println("Center");
		
		Position previus = new Position(this.getCurrent_position());
		Line line = new Line(this.getPrevius_position(),previus);
		this.setPrevius_position(previus);
		Position current = calculateNextPositionCenter(line);
		race.addPosition(current);
		this.setCurrent_position(current);
		
	}
	
	private Position calculateNextPositionRight(Line line) {
		System.out.println("Siguiente R");
		Position ps = new Position();
		int distance = (int)line.distance();
		System.out.println(distance);
		int direction = line.direction();
		switch(direction){
			//	Vertical OK
			case 1: 
					ps.setX(line.getB().getX()+1);
					ps.setY(line.getB().getY()+(distance));
					break;
			// Horizontal OK
			case 2: 
					ps.setX(line.getB().getX()+(distance+1));
					ps.setY(line.getB().getY());
					break;
			// Diag Izq Arriba OK
			case 3:
					ps.setX(line.getB().getX()-(distance-1));
					ps.setY(line.getB().getY()-(distance));
					break;
			// Diag Derecha Arriba  OK
			case 4:
					ps.setX(line.getB().getX()+(distance+1));
					ps.setY(line.getB().getY()-(distance));
					break;
			// Diag Izq Abajo OK
			case 5:
					ps.setX(line.getB().getX()-(distance-1));
					ps.setY(line.getB().getY()+(distance));
					break;
			// Diag Der Abajo OK
			case 6:
					ps.setX(line.getB().getX()+(distance+1));
					ps.setY(line.getB().getY()+(distance));
					break;

		}
		
		System.out.println(ps.toString());
		return ps;
	}
	
	
	public void moveRight() {
		System.out.println("Right");
		
		Position previus = new Position(this.getCurrent_position());
		Line line = new Line(this.getPrevius_position(),previus);
		this.setPrevius_position(previus);
		Position current = calculateNextPositionRight(line);
		race.addPosition(current);
		this.setCurrent_position(current);
		
	}	
	
	private Position calculateNextPositionDownLeft(Line line) {
		System.out.println("Siguiente DL");
		Position ps = new Position();
		int distance = (int)line.distance();
		System.out.println(distance);
		int direction = line.direction();
		switch(direction){
			//	Vertical OK
			case 1: 
					ps.setX(line.getB().getX()-1);
					ps.setY(line.getB().getY()+(distance+1));
					break;
			// Horizontal OK
			case 2: 
					ps.setX(line.getB().getX()+(distance-1));
					ps.setY(line.getB().getY()+1);
					break;
			// Diag Izq Arriba OK
			case 3:
					ps.setX(line.getB().getX()-(distance+1));
					ps.setY(line.getB().getY()-1);
					break;
			// Diag Derecha Arriba OK
			case 4:
					ps.setX(line.getB().getX()-(distance-1));
					ps.setY(line.getB().getY()-(distance-1));
					break;
			// Diag Izq Abajo OK
			case 5:
					ps.setX(line.getB().getX()-(distance+1));
					ps.setY(line.getB().getY()+(distance+1));
					break;
			// Diag Der Abajo OK
			case 6:
					ps.setX(line.getB().getX()+(distance-1));
					ps.setY(line.getB().getY()+(distance)+1);
					break;

		}
		
		System.out.println(ps.toString());
		return ps;
	}
	
	public void moveDownLeft() {
		System.out.println("Down Left");
		
		Position previus = new Position(this.getCurrent_position());
		Line line = new Line(this.getPrevius_position(),previus);
		this.setPrevius_position(previus);
		Position current = calculateNextPositionDownLeft(line);
		race.addPosition(current);
		this.setCurrent_position(current);
		
	}

	private Position calculateNextPositionDown(Line line) {
		System.out.println("Siguiente D");
		Position ps = new Position();
		int distance = (int)line.distance();
		System.out.println(distance);
		int direction = line.direction();
		switch(direction){
			//	Vertical OK
			case 1: 
					ps.setX(line.getB().getX());
					ps.setY(line.getB().getY()+(distance+1));
					break;
			// Horizontal OK
			case 2: 
					ps.setX(line.getB().getX()+(distance));
					ps.setY(line.getB().getY()+(distance-1));
					break;
			// Diag Izq Arriba OK					
			case 3:
					ps.setX(line.getB().getX()-(distance));
					ps.setY(line.getB().getY()-(distance-1));
					break;
			// Diag Derecha Arriba OK
			case 4:
					ps.setX(line.getB().getX()+(distance));
					ps.setY(line.getB().getY()-(distance-1));
					break;
			// Diag Izq Abajo OK
			case 5:
					ps.setX(line.getB().getX()-(distance));
					ps.setY(line.getB().getY()+(distance+1));
					break;
			// Diag Der Abajo OK
			case 6:
					ps.setX(line.getB().getX()+(distance));
					ps.setY(line.getB().getY()+(distance)+1);
					break;

		}
		
		System.out.println(ps.toString());
		return ps;
	}
	
	public void moveDown() {
		System.out.println("Down");
		
		Position previus = new Position(this.getCurrent_position());
		Line line = new Line(this.getPrevius_position(),previus);
		this.setPrevius_position(previus);
		Position current = calculateNextPositionDown(line);
		race.addPosition(current);
		this.setCurrent_position(current);
	}

	private Position calculateNextPositionDownRight(Line line) {
		System.out.println("Siguiente DR");
		Position ps = new Position();
		int distance = (int)line.distance();
		System.out.println("Distancia "+distance);
		int direction = line.direction();
		System.out.println("Direccion "+direction);
		switch(direction){
			//	Vertical OK
			case 1: System.out.println("Venia en Vertical");
					ps.setX(line.getB().getX()+1);
					ps.setY(line.getB().getY()+(distance+1));
					break;
			// Horizontal OK
			case 2: 
					ps.setX(line.getB().getX()+(distance+1));
					ps.setY(line.getB().getY()+(distance-1));
					break;
			// Diag Izq Arriba OK
			case 3:
					ps.setX(line.getB().getX()-(distance-1));
					ps.setY(line.getB().getY()-(distance-1));
					break;
			// Diag Derecha Arriba OK
			case 4:
					ps.setX(line.getB().getX()+(distance+1));
					ps.setY(line.getB().getY()-(distance-1));
					break;
			// Diag Izq Abajo OK
			case 5:
					ps.setX(line.getB().getX()-(distance-1));
					ps.setY(line.getB().getY()+(distance+1));
					break;
			// Diag Der Abajo 
			case 6:
					ps.setX(line.getB().getX()+(distance+1));
					ps.setY(line.getB().getY()+(distance+1));
					break;

		}
		
		System.out.println(ps.toString());
		return ps;
	}
	
	
	public void moveDownRight() {
		System.out.println("Down Right");
		
		Position previus = new Position(this.getCurrent_position());
		Line line = new Line(this.getPrevius_position(),previus);
		this.setPrevius_position(previus);
		Position current = calculateNextPositionDownRight(line);
		race.addPosition(current);
		this.setCurrent_position(current);
	}
	
	
	
}
